import datetime
import json
import os
import random
import re
import uuid
from datetime import datetime

from flask import Blueprint, request, jsonify

from utils.comm import send_message
from views.myjwt import myjwt
from utils.redisconn import RedisCon
from werkzeug.security import generate_password_hash, check_password_hash

# 容联云发送信息包

from conf.comm import sqlalchemy_context
from database import *
# 蓝图初始化
bp_users = Blueprint('users', __name__)


# 注册功能实现
@bp_users.route('/reg/', methods=['POST'])
@sqlalchemy_context()
def reg():
    # 获取vue信息
    data = request.data
    if not data:
        data = request.form
    else:
        data = json.loads(request.data)

    # 正则验证
    res = re.match('^1[3-9][0-9]{9}$', data['mobile'])
    if not res:
        return jsonify({'code': 11111, 'msg': '手机号不合法'})

    # 向数据库提交数据
    try:
        user = User(username=data['username'], password=generate_password_hash(data['password']), mobile=data['mobile'])
        db.session.add(user)
        db.session.commit()
        return jsonify({'code': 200, 'msg': '注册成功'})
    except:
        return jsonify({'code': 20020, 'msg': '用户已从在'})


# 手机短信接口
@bp_users.route('/sendcode/', methods=["POST"])
@sqlalchemy_context()
def sendcode():
    # 传递手机号
    data = request.data
    if data:
        data = json.loads(data)
    else:
        data = request.form
    mobile = data['mobile']
    r = RedisCon()
    # 有效性验证，正则验证手机号
    reg = re.match('^1[3-9]\d{9}$', data['mobile'])
    if not reg:
        return jsonify({"code": 10012, 'msg': '手机号不合法'})
    # 验证是否30秒内已经发过验证码
    code = r.get_str(mobile)
    if code:
        return jsonify({"code": 10015, 'msg': '30少内您已经发过验证码'})
    # 生成验证码
    code = str(random.randint(100000, 999999))
    # 调用短信接口
    flag = send_message(mobile, code, 1)
    if flag:
        # 发送成功，存入redis
        r.set_str(mobile, code, 60)
        # 返回结果（验证码）
        return jsonify({'code': 200, 'sendcode': code, 'msg': '发送成功，请接收'})
    else:
        return jsonify({'code': 20011, 'msg': '发送失败，请重试'})


# 登录接口
@bp_users.route('/login/', methods=["GET"])
@sqlalchemy_context()
def login():
    # 用户名登录
    username = request.args.get('username')
    password = request.args.get('password')
    mobile = request.args.get('mobile')
    code = request.args.get('code')
    # print(username,password)
    # return 'ok'
    if username:
        # 查询这个用户信息
        user = User.query.filter_by(username=username).first()
        if user:
            if check_password_hash(user.password, password):
                # 密码对 删除错误的信息记录
                Record.query.filter_by(username=username).delete()
                token = myjwt.jwt_encode({'data': {'username': user.username, 'userid': user.id}})
                return jsonify(
                    {'code': 200, 'msg': '登录成功', 'userid': user.id, 'username': user.username, 'token': token})
            else:
                # 目前时间
                print('************************************************')
                day = datetime.datetime.now()
                print(day)
                # 看看记录表错误有没有次数
                user = Record.query.filter_by(username=username).first()
                print(user)
                # 如果没有用户就添加一个新记录
                if not user:
                    rec = Record(username=username, recordtime=day, count=1)
                    db.session.add(rec)
                    db.session.commit()
                # 有数据修改 次数加一和时间更新
                else:
                    # 先判断时间 例如今天登录2次没上去不等了 然后等到24小时以后登录时间要归零 然后还有3次登录机会
                    if day.timestamp() / 3600 > user.recordtime.timestamp() / 3600 + 24:
                        Record.query.filter_by(username=username).update({'count': 0, 'recordtime': day})
                    # 没超过24小时 连续登录3次不让登录
                    if user.count < 3:
                        Record.query.filter_by(username=username).update({'count': user.count + 1})
                        db.session.commit()
                    elif user.count == 3:
                        return jsonify({'code': 20060, 'msg': '每天只有三次登录机会'})

                return jsonify({'code': 20030, 'msg': '用户名或密码错误'})
        else:
            return jsonify({'code': 20020, 'msg': '该用户不存在'})

    if mobile:
        # 手机号登录
        # 获取前端验证码
        # 获取后台验证码
        r = RedisCon()
        hcode = r.get_str(mobile)  # 得到的是b开头的二进制数据
        print(hcode)
        if hcode:
            if int(code) == int(hcode):
                # 写到数据库
                user = User.query.filter_by(mobile=mobile).first()
                if not user:
                    user = User(mobile=mobile, username=mobile)
                    db.session.add(user)
                    db.session.commit()
                r.del_str(mobile)
                token = myjwt.jwt_encode({'data': {'mobile': user.mobile, 'userid': user.id}})
                return jsonify(
                    {'code': 200, 'msg': '登录成功', 'userid': user.id, 'username': user.username, 'token': token})
            else:
                return jsonify({'code': 20050, 'msg': '验证码输入错误，请重新输入'})
        else:
            return jsonify({'code': 20040, 'msg': '验证码不存在'})


# 中间件 token除了注册和登录 其余都使用
@bp_users.before_request
def before_request():
    lst = ['/users/login/', '/users/sendcode/', '/users/reg/']
    if request.path not in lst:
        # 获取token
        try:
            token = request.headers['Token']
        except:
            return jsonify({"code": 403, 'mes': '请传递token'})
        # 解密重新对比token
        newtoken = myjwt.jwt_decode(token)
        # print(token)
        # print(newtoken)
        if newtoken and myjwt.check(token, newtoken):
            pass
        else:
            return jsonify({"code": 403, 'mes': 'token错误'})


# 用户中心
# 返回用户信息接口
@bp_users.route('/getuserinfo/', methods=['GET'])
def getuserinfo():
    userid = request.args.get('userid')
    # print(userid)
    user = User.query.filter_by(id=userid).first()
    # print(user)

    dic = {}
    dic['id'] = user.id
    dic['username'] = user.username
    dic['mobile'] = user.mobile
    dic['avater'] = user.avater

    return jsonify({'code': 200, 'list': dic})


# 图像上传
@bp_users.route('/upload/', methods=["POST"])
def upload():
    # 接收
    file = request.files['file']
    print(file)

    # 解决文件重命名问题
    # 1uuid 设计到后缀  后缀不变用os.path.splitex【1】分割 在使用uuid凭借
    filetext = os.path.splitext(file.filename)[1]  # 获取到的是.jpg .png
    newfilename = uuid.uuid4().hex + filetext  # uuid4格式456-66asd-a  加hex变asd5asd6a54d  -有时候会出问题
    # 重新创建一个文件 根据userid来创建
    userid = request.form.get('userid')
    # 判断有没有该用户名文件夹，存在直接写文件 不从在创建在写入
    path = './static/upload/' + str(userid)
    # 判断不从在 创建文件夹
    if not os.path.exists(path):
        os.mkdir(path)

    # 收到保存在upload
    file.save(os.path.join(path, newfilename))

    # 更新到数据库
    User.query.filter_by(id=userid).update({'avater': newfilename})
    db.session.commit()
    return jsonify({'code': 200, 'filename': newfilename})
